import java.lang.annotation.*;

public class Test {
    public static void main(String[] args) {
        // 元注解
        // 有一些注解可以修饰其他注解，这些注解就称为元注解。
        // 1、@Target
        // 最常用的元注解是@Target。使用@Target可以定义Annotation能够被应用于源码的哪些位置：
        // 类或接口：ElementType.TYPE；
        // 字段：ElementType.FIELD；
        // 方法：ElementType.METHOD；
        // 构造方法：ElementType.CONSTRUCTOR；
        // 方法参数：ElementType.PARAMETER。

        // 2、@Retention
        // 另一个重要的元注解@Retention定义了Annotation的生命周期：
        // 仅编译期：RetentionPolicy.SOURCE；
        // 仅class文件：RetentionPolicy.CLASS；
        // 运行期：RetentionPolicy.RUNTIME。
        // 如果@Retention不存在，则该Annotation默认为CLASS。因为通常我们自定义的Annotation都是RUNTIME

        // 3、@Repeatable
        // 使用@Repeatable这个元注解可以定义Annotation是否可重复
        // 需要新增一个容器注解

        // 4、@Inherited
        // 使用@Inherited定义子类是否可继承父类定义的Annotation。
        // @Inherited仅针对@Target(ElementType.TYPE)类型的annotation有效，并且仅针对class的继承，对interface的继承无效
        // 如果Repeatable+Inherited同时使用、那么Repeatable的容器注解也必须使用Inherited

    }
}


@Target(ElementType.TYPE) // 1、限制只能在类上使用的注解
// @Target({ElementType.METHOD, ElementType.FIELD}) // 2、只能在方法和字段上使用的注解
@Retention(RetentionPolicy.RUNTIME) // 3、运行期有效的注解
@Repeatable(Reports.class) // 4、可重复注解
@Inherited  // 5、子类可继承父类的该注解
@interface Report {
    int type() default 0;

    String level() default "info";

    String value() default "";
}

// Report的容器注解
@Inherited 
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Reports {
    Report[] value(); // 必须叫 value，且类型是 Report[]
}